package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
)

type IFormatter interface {
	Format(bs []byte) io.Reader
}

type RpcRegister struct {
	methods map[string]RpcMethodRequest
}

type RpcMethodRequest struct {
	Url        string `json:"url"`
	MethodName string `json:"method_name"`
}

type RpcMethodResponse struct {
	Success bool
}

func NewRpcRegister() *RpcRegister {
	this := &RpcRegister{
		methods: make(map[string]RpcMethodRequest),
	}
	return this
}

func (this *RpcRegister) RegisterFormatter(writer http.ResponseWriter, request *http.Request) {
	writer.WriteHeader(200)
	writer.Header().Set("Content-Type", "application/json")
	var rpcMethod RpcMethodRequest
	var resp RpcMethodResponse
	err := json.NewDecoder(request.Body).Decode(&rpcMethod)
	if err != nil {
		resp.Success = false
		str, _ := json.Marshal(&resp)
		_, _ = writer.Write(str)
		return
	}
	this.methods[rpcMethod.MethodName] = rpcMethod
	resp.Success = true
	str, _ := json.Marshal(&resp)
	_, _ = writer.Write(str)
}

func (this *RpcRegister) HasMethod(name string) bool {
	_, ok := this.methods[name]
	return ok
}

func (this *RpcRegister) Call(name string, params interface{}) ([]byte, error) {
	v, ok := this.methods[name]
	if !ok {
		return nil, errors.New("call method %s failed")
	}
	var resp *http.Response
	var err error
	if bs, ok := params.([]byte); ok {
		resp, err = http.Post(v.Url, "application/json; charset=utf-8", bytes.NewReader(bs))
		if err != nil {
			return nil, err
		}
	} else {
		var buf bytes.Buffer
		err := json.NewEncoder(&buf).Encode(params)
		if err != nil {
			return nil, err
		}
		resp, err = http.Post(v.Url, "application/json; charset=utf-8", &buf)
	}
	bs, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return bs, nil
}

func init() {
	//mux.HandleFunc("/api/registerFormatter", GlobalManager.RpcRegister.RegisterFormatter)
}
